package com.xiaobai.aroundtest.aspect;

import com.xiaobai.aroundtest.annotation.AroundTest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author wangtw
 * @date 2023/12/6 0:47
 * @description
 */
@Aspect
@Component
@Slf4j
public class AroundTestAspect {

    @Around("@annotation(aroundTest)")
    public Object around(ProceedingJoinPoint point, AroundTest aroundTest) {
        // 获取参数名称
        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        String[] parameterNames = methodSignature.getParameterNames();
        // 获取参数
        Object[] args = point.getArgs();
        for (int i = 0; i < parameterNames.length; i++) {
            if (parameterNames[i].equals(aroundTest.name())) {
                log.info("保存{}为{}的文章", parameterNames[i], args[i]);
            }
        }

        String info = "";
        for (Object arg : args) {
            if (arg instanceof String) {

            } else {
                // 获取文章信息
                PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(arg.getClass());
                for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                    if (!String.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
                        continue;
                    }
                    Method readMethod = propertyDescriptor.getReadMethod();
                    if (readMethod == null) {
                        continue;
                    }

                    Object propertyValue = null;
                    try {
                        propertyValue = readMethod.invoke(arg, null);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }

                    info = info.concat(propertyDescriptor.getName())
                            .concat(":")
                            .concat(propertyValue == null ? "" : propertyValue.toString())
                            .concat(",");
                }
            }
        }
        Object result = null;
        try {
            result = point.proceed(point.getArgs());
        } catch (Throwable e) {
            e.printStackTrace();
            log.error("方法异常，文章信息：{}", info);
        }
        log.info("修改成功, 文章信息:{}", info);
        return result;
    }
}
